package com.hiedu.handler;
import com.hiedu.commons.R;
import com.hiedu.commons.ServiceCode;
import com.hiedu.commons.ServiceException;
import com.mysql.cj.log.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @ProjectName: hi-app
 * @Titile: GlobalExceptionHandler
 * @Author: Lucky
 * @Description: 全局异常处理
 */
@RestControllerAdvice //异常增强 AOP
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 对业务异常进行统一处理
     * 注意：校验框架抛出的异常，在这个异常处理类中不能正确处理，需要进行优化，未完待续，明天再讲
     * 系统中只要是出现了ServiceException，都是被这个方法处理
     */
    @ExceptionHandler
    public R<Void> serviceHandler(ServiceException e) {
        return R.fail(e);
    }

    @ExceptionHandler
    public R<Void> serviceHandler(BindException e) {
        log.warn("BindException:{}",e.getMessage());
        R<Void> r = new R<>();
        r.setCode(ServiceCode.ERROR_BAD_REQUEST.getCode());
        String message = e.getFieldError().getDefaultMessage();
        r.setMessage(message);
        return r;
    }

    /**
     * 获取数据后，进行数据转换，出现异常
     * @param e
     * @return
     */
    @ExceptionHandler
    public R<Void> serviceHandler(HttpMessageConversionException e) {
        R<Void> r = new R<>();
        r.setCode(ServiceCode.ERROR_BAD_REQUEST.getCode());
        String message = "传递的数据转换出现异常，请检查数据的值或类型";
        r.setMessage(message);
        return r;
    }

    /**
     * 处理其他异常
     * 这个异常处理会把异常信息直接返回到前端，项目在开发中，出现了异常，需要在
     * 这个类中加异常处理方法
     *
     * @param e
     * @return
     */
    @ExceptionHandler
    public R<Void> serviceHandler(Throwable e) {
        log.debug("其他异常:{}",e.getMessage());
        // 切记，在上线后一定要删除此代码，因为它是堵塞式的
        //e.printStackTrace();
        //如果在开发中出现此消息，那么一定要检查后台程序，并且必须处理。
        String message = "服务器忙,请稍后再试!";
        //构建一个业务异常
        ServiceException exception = new
                ServiceException(ServiceCode.ERROR_NOT_KNOW, message);
        return R.fail(exception);
    }
}
